package net.aiion.weave.util.net;

public final class URLEncoder implements Encoder
{
    private static final Encoder ENCODER_INSTANCE = new URLEncoder();

    private URLEncoder() {
    }

    @Override
    public String encode(final String s) {
        // Source: http://www.ietf.org/rfc/rfc1738.txt
        final StringBuilder sb = new StringBuilder();
        for (int i = 0; i < s.length(); i++) {
            final char c = s.charAt(i);
            if (c > 0x1F && c < 0x7F) {
                switch (c) {
                // Unsafe characters
                case ' ':
                case '<':
                case '>':
                case '"':
                case '#':
                case '%':
                case '{':
                case '}':
                case '|':
                case '\\':
                case '^':
                case '~':
                case '[':
                case ']':
                case '`':
                    final String tmp = "0" + Integer.toHexString(c);
                    sb.append('%').append(tmp.substring(tmp.length() - 2));
                    break;
                default:
                    sb.append(c);
                    break;
                }
            } else {
                sb.append('%').append(Integer.toHexString(s.charAt(i)));
            }
        }
        return sb.toString();
    }

    public static Encoder getInstance() {
        return ENCODER_INSTANCE;
    }
}
